#include "DSP28x_Project.h"
#include "stream_cipher.h"
#include <string.h>

// --- LCG (伪随机数生成器) 参数 (与上位机端完全相同) ---
#define PRNG_MULTIPLIER 137
#define PRNG_INCREMENT  171
#define PRNG_MODULUS    256

/**
 * @brief 通过XOR折叠从密钥字节派生一个32位整数种子
 * @param key       指向密钥数组的指针
 * @param key_len   密钥的长度 (应为16)
 * @return 计算出的32位种子值
 */
static uint32_t derive_seed_from_key_bytes(const unsigned char * key, size_t key_len) {
    if (key == NULL || key_len == 0) {
        return 0;
    }

    uint32_t seed = 0;
    uint32_t chunk_int;
    size_t i=0;
    // 将16字节的密钥看作4个4字节的整数，进行XOR
    for (i = 0; i < key_len; i += 4) {
        // 使用memcpy来安全地从字节数组中读取一个32位整数，避免对齐问题
        // 确保我们不会读取超过key_len的范围
        if (i + 4 <= key_len) {
            memcpy(&chunk_int, &key[i], sizeof(uint32_t));
            seed ^= chunk_int;
        }
    }
    return seed;
}

/**
 * @brief 对数据缓冲区进行流密码解密 (或加密)
 */
void stream_cipher_process(unsigned char* data, size_t length, const unsigned char* key, size_t key_len) {
    if (data == NULL || length == 0 || key == NULL) {
        return;
    }

    uint32_t seed = derive_seed_from_key_bytes(key, key_len);
    uint32_t current_prn = seed; // PRNG的当前状态
    size_t i = 0;
    for (i = 0; i < length; i++) {
        // LCG: X_n+1 = (a * X_n + c) mod m
        current_prn = (PRNG_MULTIPLIER * current_prn + PRNG_INCREMENT) % PRNG_MODULUS;

        // 使用生成的伪随机字节与数据进行异或
        data[i] = data[i] ^ (unsigned char)current_prn;
    }
}
